﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "AddNewFamilyTypeDlg.h"
#include "IElementParameters.h"
#include "IElementBasicInformation.h"
#include "IInstanceType.h"
#include "IDocument.h"
#include "IFamily.h"
#include "GmStyleSheetHelper.h"
#include "EditComponentTypeDlg.h"


#include "IApplication.h"
#include "IMainWindow.h"
#include "IUserTransaction.h"

#include "UiCommonDialog.h"
#include "IFamilyType.h"
#include "UiPlatformUtils.h"
#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

using namespace gcmp;

AddNewFamilyTypeDlg::AddNewFamilyTypeDlg(gcmp::IDocument* pDoc, gcmp::IType* pType, QWidget *parent)
    : QDialog(parent, Qt::FramelessWindowHint)
    , m_pType(pType)
    , m_pDoc(pDoc)
{
    m_ui.setupUi(this);

    std::wstring styleSheetStr = GmStyleSheetHelper::Instance()->GetCurrentStyleData();
    setStyleSheet(QString::fromStdWString(styleSheetStr));

    m_ui.gbmp_title->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
    m_ui.gbmp_title->setIconVisible(false);
    m_ui.gbmp_title->setMaxButtonVisible(false);
    m_ui.gbmp_title->setMinButtonVisible(false);
    m_ui.gbmp_title->setText(QString::fromStdWString(GBMP_TR(L"新建类型")));
    m_ui.pushButton_Ok->setObjectName(QStringLiteral("AddNewFamilyTypeDlg_pushButton_Ok"));
    m_ui.pushButton_Cancel->setObjectName(QStringLiteral("AddNewFamilyTypeDlg_pushButton_Cancel"));
    this->setProperty("use_gbmp_title", true);

    const std::wstring name = m_pType->GetBasicInformation()->GetName();
    if (parent)
    {
        m_ui.lineEdit_NewTypeName->setText(QString::fromStdWString(name));
    }
    else
    {
        m_ui.lineEdit_NewTypeName->setText(QString::fromStdWString(GBMP_TR(name + L"_新建")));
    }
    m_ui.lineEdit_NewTypeName->setFocus();
    m_ui.lineEdit_NewTypeName->selectAll();

    // 消息处理。
    QObject::connect(m_ui.gbmp_title, &GmTitleBar::closeRequested, this, &AddNewFamilyTypeDlg::reject);
    QObject::connect(m_ui.gbmp_title, &GmTitleBar::moveRequested, this, &AddNewFamilyTypeDlg::OnMoveRequested);

    QObject::connect(m_ui.pushButton_Ok, SIGNAL(clicked()), this, SLOT(OnClickOK()));
    QObject::connect(m_ui.pushButton_Cancel, SIGNAL(clicked()), this, SLOT(OnClickCancel()));
}

void AddNewFamilyTypeDlg::OnMoveRequested(const QPoint& cursorPos, const QPoint& offset)
{
    Q_UNUSED(cursorPos);
    move(pos() + offset);
}

bool AddNewFamilyTypeDlg::InputNameIsValid(const std::wstring& name)
{
    IInstanceType* pInstanceType = dynamic_cast<IInstanceType*>(m_pType);
    if (pInstanceType != nullptr)
    {
        std::vector<const IFamilyType*> fmTypes;
        if (pInstanceType->IsSub())
        {
            DBG_WARN_AND_RETURN_FALSE_UNLESS(m_pDoc, L"当前文档为空",L"GDMPLab",L"2024-03-30");
            IFamily* pTopFamily =quick_cast<IFamily> (m_pDoc->GetElement(pInstanceType->GetTopFamilyId()));
            DBG_WARN_AND_RETURN_UNLESS(pTopFamily != nullptr, false, L"pFamily为空！",L"GDMPLab",L"2024-03-30");
            fmTypes = pTopFamily->GetAllSubFamilyTypesBySubInstanceType(pInstanceType);
        }
        else
        {
            IFamily* pFamily = pInstanceType->GetFamily();
            DBG_WARN_AND_RETURN_UNLESS(pFamily != nullptr, false, L"pFamily为空！",L"GDMPLab",L"2024-03-30");
            fmTypes = pFamily->GetFamilyTypes();
        }
        
        FOR_EACH(type, fmTypes)
        {
            if (name == type->GetName())
            {
                return false;
            }
        }
        return true;
    }

    IElementBasicInformation* pElementBasicInformation = m_pType->GetBasicInformation();
    DBG_WARN_AND_RETURN_UNLESS(pElementBasicInformation, false, L"获取BasicInformation失败",L"GDMPLab",L"2024-03-30");
    OwnerPtr<ElementFilterExceptFamilyAndType> filter = NEW_AS_OWNER_PTR(ElementFilterExceptFamilyAndType);
    std::vector<IElement*> allElements = m_pType->GetDocument()->GetElementsByCategory(pElementBasicInformation->GetCategoryUid(), filter.get());
    FOR_EACH(ele, allElements)
    {
        if (name == ele->GetBasicInformation()->GetName())
        {
            return false;
        }
    }
    return true;

}

void AddNewFamilyTypeDlg::OnClickOK()
{
    if (m_pType == nullptr) 
        return;

    ElementId typeId = ElementId::InvalidID;
    std::wstring name = m_ui.lineEdit_NewTypeName->text().toStdWString();
    if (!InputNameIsValid(name))
    {
        UiCommonDialog::ShowMessageBox(GBMP_TR(L"新建类型"), GBMP_TR(L"该类型名称已使用！"), (int)UiCommonDialog::ButtonType::OK);
        return;
    }

    QDialog::accept();

    if (!parent())
    {// 修改参数的对话框(EditComponentTypeDlg)不存在时
        gcmp::OwnerPtr<IUserTransaction> ut = IUserTransaction::Create(m_pDoc, (GBMP_TR(L"新建族类型")));
        {
            IInstanceType* pInstanceType = dynamic_cast<IInstanceType*>(m_pType);
            if (pInstanceType != nullptr)
            {
                if (pInstanceType->IsSub())
                {
                    DBG_WARN_AND_RETURN_VOID_UNLESS(m_pDoc, L"当前文档为空",L"GDMPLab",L"2024-03-30");
                    IFamily* pTopFamily = quick_cast<IFamily> (m_pDoc->GetElement(pInstanceType->GetTopFamilyId()));
                    DBG_WARN_AND_RETURN_VOID_UNLESS(pTopFamily, L"pFamily为空！",L"GDMPLab",L"2024-03-30");
                    const IFamilyType* pCurrentFamilyType = pTopFamily->GetSubFamilyTypeBySubInstanceType(pInstanceType);
                    DBG_WARN_AND_RETURN_VOID_UNLESS(pCurrentFamilyType, L"获取当前组类型为空",L"GDMPLab",L"2024-03-30");
                    OwnerPtr<IFamilyType> opNewFamilyType = IFamilyType::Create(name, pCurrentFamilyType);
                    DBG_WARN_AND_RETURN_VOID_UNLESS(opNewFamilyType, L"新构件类型创建失败",L"GDMPLab",L"2024-03-30");
                    pTopFamily->AddSubFamilyType(pInstanceType->GetSubFamilyIdPath(), opNewFamilyType.get());
                    IInstanceType* pNewInstanceType = pTopFamily->CreateSubInstanceType(pInstanceType->GetSubFamilyIdPath(), name);
                    DBG_WARN_AND_RETURN_VOID_UNLESS(pNewInstanceType, L"实例类型创建失败",L"GDMPLab",L"2024-03-30");
                    typeId = pNewInstanceType->GetBasicInformation()->GetElementId();
                }
                else
                {
                    IFamily* pFamily = pInstanceType->GetFamily();
                    DBG_WARN_AND_RETURN_VOID_UNLESS(pFamily != nullptr, L"pFamily为空！",L"GDMPLab",L"2024-03-30");
                    const IFamilyType* pOldFamilyType = ((const IFamily*)pFamily)->GetFamilyTypeByName(pInstanceType->GetBasicInformation()->GetName());
                    DBG_WARN_AND_RETURN_VOID_UNLESS(pOldFamilyType != nullptr, L"FamilyType为空！",L"GDMPLab",L"2024-03-30");
                    OwnerPtr<IFamilyType> newFamilyType = IFamilyType::Create(name, pOldFamilyType);
                    DBG_WARN_AND_RETURN_VOID_UNLESS(newFamilyType, L"新构件类型创建失败",L"GDMPLab",L"2024-03-30");
                    pFamily->AddFamilyType(newFamilyType.get());
                    IInstanceType* pInstanceType = quick_cast<IInstanceType>(pFamily->CreateInstanceType(name));
                    DBG_WARN_AND_RETURN_VOID_UNLESS(pInstanceType, L"实例类型创建失败",L"GDMPLab",L"2024-03-30");
                    typeId = pInstanceType->GetBasicInformation()->GetElementId();
                }
            }
            else
            {
                IType* pNewType = m_pType->CreateBaseOnSelf();
                typeId = pNewType->GetBasicInformation()->GetElementId();
                pNewType->GetBasicInformation()->SetCategoryUid(m_pType->GetBasicInformation()->GetCategoryUid());
                std::vector<OwnerPtr<IParameter>> allParameter = m_pType->GetElementParameters()->GetAllParameters();
                FOR_EACH(param, allParameter)
                {
                    pNewType->GetElementParameters()->AddEmbeddedParameter(param.get());
                }
            }
        }
        ut->Commit();

        // 新建参数对话框 EditComponentTypeDlg
        EditComponentTypeDlg* pDlg = NEW_AS_QT_CHILD(EditComponentTypeDlg, m_pDoc, typeId, dynamic_cast<QWidget*>(IMainWindow::GetMainWindow()));
        pDlg->setTypeName(m_ui.lineEdit_NewTypeName->text());
        int rt = pDlg->exec();
        if (rt != QDialog::Accepted)
        {
            return;
        }
    }
    else
    {
        EditComponentTypeDlg* pTypeParamDlg = dynamic_cast<EditComponentTypeDlg*>(parent());
        DBG_WARN_AND_RETURN_VOID_UNLESS(pTypeParamDlg != nullptr, L"EditComponentTypeDlg真的不存在吗？",L"GDMPLab",L"2024-03-30");
        pTypeParamDlg->setTypeName(m_ui.lineEdit_NewTypeName->text());
    }
}

void AddNewFamilyTypeDlg::OnClickCancel()
{
    QDialog::reject();
}


